﻿using System;
using System.Web;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.IO;

namespace LiveService
{
    [DataContract]
    public class ChunksReceptor
    {
        List<Chunk>     chunklist = null;
        ChunksInfo      chunkinfo = null;
        bool            initialized = false;

        public ChunksReceptor()
        {
            ;
        }

        // Update parent folder size with the current chunked
        // File size.
        private bool UpdateFolderSize()
        {
            try
            {
                LiveServiceOrmDataContext db = new LiveServiceOrmDataContext();
                Folder fold = db.Folder.SingleOrDefault(c => c.id == this.chunkinfo.Parentid);
                fold.size += this.chunkinfo.Fileinfo.size;
                db.SubmitChanges();
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                LService.errmsg = "Error : folder size cannot be updated ! Please contact Administrator.";
                return false;
            }
        }

        private bool FinalizeUploadDatabase(LiveService.File Fileinfo, System.Guid Parentid, string folderpath)
        {
            try
            {
                LiveServiceOrmDataContext db = new LiveServiceOrmDataContext();
                File nfile = new File();

                nfile.name = Fileinfo.name;
                nfile.size = Fileinfo.size;
                nfile.extension = Fileinfo.extension;
                nfile.createdon = DateTime.Now;
                nfile.folderid = Parentid;
                nfile.id = System.Guid.NewGuid();
                nfile.internalpath = folderpath;
                db.File.InsertOnSubmit(nfile);
                db.SubmitChanges();
                return true;
            }
            catch (Exception ex)
            {
                LService.errmsg = "Error : unable to save file in database ! " + ex.Message;
                return false;
            }
        }

        public string GetFolderFilePath(System.Guid Parentid)
        {
            try
            {
                LiveServiceOrmDataContext db = new LiveServiceOrmDataContext();
                Folder fold = db.Folder.SingleOrDefault(c => c.id == Parentid);
                string finalFolder = fold.internalpath;
                return finalFolder;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                LService.errmsg = "Error : unable to retrieve folder (id == " + Parentid.ToString() + ") path in database ! Please contact Administrator.";
                return null;
            }
        }

        public bool ReceiveChunk(byte[] datas, System.Guid Parentid, LiveService.File Fileinfo, System.Guid Userid)
        {
            if (datas.Length == 0) {
                LService.errmsg = "ch null";
                return false;
            }
            else
            {
            try
            {
                string folderpath = this.GetFolderFilePath(Parentid);
                if (folderpath != null)
                {
                    if (System.IO.Directory.Exists(folderpath))
                    {
                        string finalstr = string.Format("{0}{1}", folderpath + @"\", Fileinfo.name.Trim());
                        if (System.IO.File.Exists(finalstr))
                            AppendReceivedChunk(datas, folderpath, Fileinfo.name.Trim());
                         else
                            OpenReceivedUpload(datas, folderpath, Fileinfo.name.Trim());
                        if (datas.Length < 15000) // inferieur a chunksize, donc dernier (ou unique)
                        {
                            LService.errmsg = "Error : FINALIZE DB";
                            FinalizeUploadDatabase(Fileinfo, Parentid, folderpath);
                 
                        }
                        return true;
                    }
                    else
                    {
                        LService.errmsg = "Error : the file folder (" + folderpath + ") doesn't exist on server ! Please contact Administrator.";
                        return false;
                    }
                }
                else
                {
                    LService.errmsg = "Error : the file folder is null";
                    return false;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                LService.errmsg = "Error : unable to save file on server ! Please contact administrator";
                return false;
            }
            }

        }

        private void AppendReceivedChunk(byte[] datas, string folderpath, string filename)
        {
            try
            {
                string finalstr = string.Format("{0}{1}", folderpath + @"\", filename.Trim());
                FileStream fs = new FileStream(finalstr, System.IO.FileMode.Append, System.IO.FileAccess.Write);
                fs.Write(datas, 0, datas.Length);
                fs.Close();
                
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                LService.errmsg = "Error : unable to append chunk " + ex.Message;
            }
        }

        private void OpenReceivedUpload(byte[] datas, string folderpath, string filename)
        {
            try
            {
                string finalstr = string.Format("{0}{1}", folderpath + @"\", filename.Trim());
                FileStream fs = new FileStream(finalstr, System.IO.FileMode.Create, System.IO.FileAccess.Write);
                fs.Write(datas, 0, datas.Length);
                fs.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                LService.errmsg = "Error : unable to open chunk " + ex.Message;
            }
        }
    }
}